import re
import sys
import os
import winreg
import threading
import time
import logging
import subprocess
from PyQt5.QtWidgets import (QApplication, QWidget, QSystemTrayIcon, QMenu,
                             QAction, QStyle, QMessageBox, QDesktopWidget)
from PyQt5.QtCore import Qt, QPoint, pyqtSignal, QObject, QTimer, QSettings
from PyQt5.QtGui import QPainter, QColor, QFont, QIcon, QPixmap

# 配置日志
logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s - %(levelname)s - %(message)s'
)


class SignalEmitter(QObject):
    """用于在子线程中发射信号的辅助类"""
    update_signal = pyqtSignal(str, list, dict)  # 当前信息, 账户列表, 当前账户


class SimpleAccountMenu(QMenu):
    """账户选择菜单"""

    def __init__(self, parent=None):
        super().__init__(parent)
        # 设置菜单为无边框+透明背景
        self.setWindowFlags(self.windowFlags() | Qt.FramelessWindowHint | Qt.NoDropShadowWindowHint)
        self.setAttribute(Qt.WA_TranslucentBackground)
        # 设置简洁样式
        self.setStyleSheet("""
            QMenu {
                background-color: rgba(255, 255, 255, 230);
                border-radius: 8px;
                padding: 10px 5px;
                border: 1px solid rgba(180, 180, 180, 120);
                font-family: 'Microsoft YaHei';
                font-size: 13px;
                min-width: 150px;
            }
            QMenu::item {
                color: #333333;
                padding: 8px 15px;
                margin: 3px 0;
                border-radius: 4px;
                background-color: rgba(255, 255, 255, 100);
            }
            QMenu::item:selected {
                background-color: rgba(52, 152, 219, 180);
                color: white;
            }
            QMenu::item:disabled {
                color: #888888;
                background-color: rgba(240, 240, 240, 180);
            }
        """)


class TransparentWindow(QWidget):
    def __init__(self):
        super().__init__()
        logging.debug("窗口初始化开始")
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.SubWindow)
        self.setAttribute(Qt.WA_TranslucentBackground)

        # 初始化配置管理器
        self.settings = QSettings("SteamInfoApp", "WindowPosition")

        # 从配置文件读取上次位置
        default_pos = QPoint(100, 100)
        saved_pos = self.settings.value("window_position", default_pos)
        self.move(saved_pos)

        self.resize(400, 60)
        self.dragging = False
        self.offset = None
        self.minimize_button_rect = None
        self.switch_button_rect = None
        self.minimize_button_hover = False  # 在__init__中初始化
        self.switch_button_hover = False  # 在__init__中初始化
        self.current_info = "正在获取Steam信息..."
        self.steam_accounts = []
        self.current_account = None
        self.tray_icon = None

        # 创建信号发射器
        self.signal_emitter = SignalEmitter()
        self.signal_emitter.update_signal.connect(self.update_info)

        # 初始化托盘图标
        self.initialize_tray_icon()

        # 启动更新线程
        self.update_thread = threading.Thread(target=self.update_loop, daemon=True)
        self.update_thread.start()
        logging.debug(f"窗口初始化完成，位置: {self.pos().x()},{self.pos().y()}")


    def initialize_tray_icon(self):
        """确保托盘图标正确初始化"""
        try:
            # 绘制默认托盘图标
            if not self.tray_icon:
                self.tray_icon = QSystemTrayIcon(self)

            # 创建一个透明的QPixmap
            pixmap = QPixmap(24, 24)
            pixmap.fill(Qt.transparent)
            # 创建QPainter并设置背景透明
            painter = QPainter(pixmap)
            painter.setRenderHint(QPainter.Antialiasing)
            painter.setBrush(QColor(52, 152, 219, 150))  # 半透明蓝色
            painter.setPen(Qt.NoPen)
            painter.drawEllipse(0, 0, 24, 24)
            painter.end()
            # 设置托盘图标
            self.tray_icon.setIcon(QIcon(pixmap))

            # 创建托盘菜单
            tray_menu = QMenu()
            show_action = QAction("显示窗口", self)
            show_action.triggered.connect(self.show_window)
            hide_action = QAction("隐藏窗口", self)
            hide_action.triggered.connect(self.hide)
            refresh_action = QAction("刷新账户", self)
            refresh_action.triggered.connect(self.manual_refresh)
            quit_action = QAction("退出程序", self)
            quit_action.triggered.connect(self.quit_app)

            tray_menu.addAction(show_action)
            tray_menu.addAction(hide_action)
            tray_menu.addAction(refresh_action)
            tray_menu.addSeparator()
            tray_menu.addAction(quit_action)

            self.tray_icon.setContextMenu(tray_menu)
            self.tray_icon.activated.connect(self.on_tray_activated)
            self.tray_icon.show()
            logging.debug("托盘图标已显示")

        except Exception as e:
            logging.error(f"初始化托盘图标失败: {e}")
            try:
                # 尝试使用系统默认图标
                self.tray_icon.setIcon(QApplication.style().standardIcon(QStyle.SP_ComputerIcon))
                self.tray_icon.show()
            except:
                logging.critical("无法创建任何托盘图标")

    def on_tray_activated(self, reason):
        """处理托盘图标激活事件"""
        if reason == QSystemTrayIcon.DoubleClick:
            self.show_window()

    def show_tray_message(self, title, message):
        """安全显示托盘消息"""
        try:
            if self.tray_icon and self.tray_icon.isVisible():
                self.tray_icon.showMessage(title, message, QSystemTrayIcon.Information, 2000)
            else:
                self.initialize_tray_icon()
                QTimer.singleShot(500,
                                  lambda: self.tray_icon.showMessage(title, message, QSystemTrayIcon.Information, 2000))
        except Exception as e:
            logging.error(f"显示托盘消息失败: {e}")

    def show_window(self):
        """显示窗口并设置为活动状态"""
        self.show()
        self.activateWindow()

    def save_window_position(self):
        """保存当前窗口位置到配置文件"""
        current_pos = self.pos()
        self.settings.setValue("window_position", current_pos)

    def quit_app(self):
        """退出应用程序"""
        self.save_window_position()
        if self.tray_icon:
            self.tray_icon.hide()
        QApplication.quit()

    def get_steam_path(self):
        """注册表获取Steam安装路径"""
        try:
            key = winreg.OpenKey(winreg.HKEY_CURRENT_USER, r"Software\Valve\Steam")
            steam_path, _ = winreg.QueryValueEx(key, "SteamPath")
            winreg.CloseKey(key)
            return steam_path.replace('/', '\\')
        except Exception as e:
            logging.error(f"读取Steam注册表失败: {e}")
            return None

    def getSteamInfo(self):
        steam_path = self.get_steam_path()
        if not steam_path:
            return "无法获取Steam安装路径", [], None

        steam_config_path = f"{steam_path}\\config\\loginusers.vdf"

        if not os.path.exists(steam_config_path):
            return "Steam配置文件不存在，请确认Steam是否正确安装", [], None

        try:
            with open(steam_config_path, 'r', encoding='utf-8') as f:
                content = f.read()

            user_pattern = re.compile(r'"(\d+)"\s*\{([^}]+)\}')
            users = user_pattern.findall(content)

            current_user = None
            all_users = []
            for steam_id, user_data in users:
                account_name = re.search(r'"AccountName"\s*"([^"]+)"', user_data)
                persona_name = re.search(r'"PersonaName"\s*"([^"]+)"', user_data)
                most_recent = re.search(r'"MostRecent"\s*"1"', user_data) is not None

                if account_name and persona_name:
                    user_info = {
                        'steam_id': steam_id,
                        'account_name': account_name.group(1),
                        'persona_name': persona_name.group(1),
                        'most_recent': most_recent
                    }
                    all_users.append(user_info)

                    if most_recent:
                        current_user = user_info
                    elif current_user is None:
                        current_user = user_info

            if current_user:
                return "当前用户: " + current_user['persona_name'], all_users, current_user
            else:
                return "未找到登录用户信息", all_users, None

        except Exception as e:
            return f"读取Steam配置文件时出错: {str(e)}", [], None

    def update_loop(self):
        """更新Steam"""
        while True:
            current_info, accounts, current_account = self.getSteamInfo()
            self.steam_accounts = accounts
            self.current_account = current_account
            self.signal_emitter.update_signal.emit(current_info, accounts, current_account)
            time.sleep(5)

    def update_info(self, info, accounts, current_account):
        """更新显示的信息"""
        self.current_info = info
        self.steam_accounts = accounts
        self.current_account = current_account
        self.update()

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)

        # 绘制半透明白色背景
        rect = self.rect().adjusted(5, 5, -5, -5)
        painter.setBrush(QColor(255, 255, 255, 100))
        painter.setPen(Qt.NoPen)
        painter.drawRoundedRect(rect, 8, 8)

        # 绘制文字
        painter.setPen(QColor(0, 0, 0))
        font = QFont("Microsoft YaHei", 10)
        painter.setFont(font)

        # 计算文字区域
        text_rect = QPoint(rect.x() + 10, rect.y()), QPoint(
            rect.x() + rect.width() - 100, rect.y() + rect.height())

        painter.drawText(
            text_rect[0].x(), text_rect[0].y(),
            text_rect[1].x() - text_rect[0].x(),
            text_rect[1].y() - text_rect[0].y(),
            Qt.AlignVCenter, self.current_info
        )

        # 绘制按钮区域
        button_size = 24
        button_margin = 8
        minimize_button_x = rect.x() + rect.width() - button_size - button_margin
        minimize_button_y = rect.y() + (rect.height() - button_size) // 2

        # 最小化按钮区域
        self.minimize_button_rect = QPoint(minimize_button_x, minimize_button_y), QPoint(
            minimize_button_x + button_size, minimize_button_y + button_size)

        if self.minimize_button_hover:
            painter.setBrush(QColor(52, 152, 219, 200))
        else:
            painter.setBrush(QColor(52, 152, 219, 150))

        painter.drawEllipse(self.minimize_button_rect[0].x(), self.minimize_button_rect[0].y(), button_size,
                            button_size)

        # 最小化按钮横线
        painter.setPen(QColor(255, 255, 255))
        line_y = self.minimize_button_rect[0].y() + button_size // 2
        painter.drawLine(self.minimize_button_rect[0].x() + 8, line_y,
                         self.minimize_button_rect[0].x() + button_size - 8, line_y)

        # 账号切换按钮区域
        switch_button_x = minimize_button_x - button_size - button_margin
        switch_button_y = minimize_button_y

        self.switch_button_rect = QPoint(switch_button_x, switch_button_y), QPoint(switch_button_x + button_size,
                                                                                   switch_button_y + button_size)

        # 账号切换按钮颜色
        if self.switch_button_hover:
            painter.setBrush(QColor(75, 180, 100, 200))
        else:
            painter.setBrush(QColor(75, 180, 100, 150))

        painter.drawEllipse(self.switch_button_rect[0].x(), self.switch_button_rect[0].y(), button_size, button_size)

        # 账号切换按钮图标 (简单的"S"符号)
        painter.setPen(QColor(255, 255, 255))
        painter.setFont(QFont('Arial', 10))
        painter.drawText(self.switch_button_rect[0].x() + 4, self.switch_button_rect[0].y() + 18, "☯")

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            # 账号切换按钮点击
            if (self.switch_button_rect and
                    self.switch_button_rect[0].x() <= event.pos().x() <= self.switch_button_rect[1].x() and
                    self.switch_button_rect[0].y() <= event.pos().y() <= self.switch_button_rect[1].y()):
                self.show_account_menu(event.globalPos())

            # 最小化按钮点击
            elif (self.minimize_button_rect and
                  self.minimize_button_rect[0].x() <= event.pos().x() <= self.minimize_button_rect[1].x() and
                  self.minimize_button_rect[0].y() <= event.pos().y() <= self.minimize_button_rect[1].y()):
                self.hide()
                self.show_tray_message("Steam用户信息", "窗口已隐藏到系统托盘")
            else:
                # 开始拖动窗口
                self.dragging = True
                self.offset = event.pos()

    def show_account_menu(self, pos):
        """账户选择菜单"""
        if not self.steam_accounts:
            QMessageBox.warning(self, "无账户", "没有找到可用的Steam账户")
            return

        # 创建简洁菜单
        menu = SimpleAccountMenu(self)

        for account in self.steam_accounts:
            # 判断是否是当前账户
            is_current = self.current_account and account['account_name'] == self.current_account['account_name']
            action_text = f"{account['persona_name']} ({account['account_name']})"
            action = menu.addAction(action_text)
            action.setData(account['account_name'])
            if is_current:
                action.setEnabled(False)

        # 连接菜单选择事件
        menu.triggered.connect(self.on_account_selected)

        # 自动调整位置
        screen_geo = QDesktopWidget().screenGeometry()
        menu.adjustSize()
        menu_width = menu.sizeHint().width()
        menu_height = menu.sizeHint().height()

        if pos.x() + menu_width > screen_geo.width():
            pos.setX(screen_geo.width() - menu_width - 10)
        if pos.y() + menu_height > screen_geo.height():
            pos.setY(screen_geo.height() - menu_height - 10)

        menu.exec_(pos)

    def on_account_selected(self, action):
        account_name = action.data()
        steam_path = self.get_steam_path()
        if not steam_path:
            QMessageBox.critical(self, "路径错误", "无法获取Steam安装路径")
            return

        steam_exe = os.path.join(steam_path, 'steam.exe')
        if not os.path.exists(steam_exe):
            QMessageBox.critical(self, "路径错误", "无法找到Steam可执行文件")
            return

        # 启动Steam登录指定账户
        cmd = f'"{steam_exe}" -login {account_name}'
        try:
            # 杀死steam进程
            subprocess.run("taskkill /f /im steam.exe", shell=True)
            subprocess.Popen(cmd, shell=True)
            self.show_tray_message("启动成功", f"正在启动Steam并登录账户: {account_name}")
        except Exception as e:
            QMessageBox.critical(self, "启动失败", f"无法启动Steam: {str(e)}")

    def mouseMoveEvent(self, event):
        # 更新最小化按钮悬停状态
        if self.minimize_button_rect:
            in_button = (self.minimize_button_rect[0].x() <= event.pos().x() <= self.minimize_button_rect[1].x() and
                         self.minimize_button_rect[0].y() <= event.pos().y() <= self.minimize_button_rect[1].y())
            if in_button != self.minimize_button_hover:
                self.minimize_button_hover = in_button
                self.update()

        # 更新账号切换按钮悬停状态
        if self.switch_button_rect:
            in_switch_button = (self.switch_button_rect[0].x() <= event.pos().x() <= self.switch_button_rect[1].x() and
                                self.switch_button_rect[0].y() <= event.pos().y() <= self.switch_button_rect[1].y())
            if in_switch_button != self.switch_button_hover:
                self.switch_button_hover = in_switch_button
                self.update()

        # 处理窗口拖动
        if self.dragging and self.offset is not None:
            self.move(event.globalPos() - self.offset)

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton and self.dragging:
            self.save_window_position()
            self.dragging = False
            self.offset = None

    def mouseDoubleClickEvent(self, event):
        if event.button() == Qt.LeftButton:
            threading.Thread(target=self.manual_refresh, daemon=True).start()

    def manual_refresh(self):
        """手动刷新"""
        current_info, accounts, current_account = self.getSteamInfo()
        self.steam_accounts = accounts
        self.current_account = current_account
        self.signal_emitter.update_signal.emit(current_info, accounts, current_account)

    def closeEvent(self, event):
        """重写关闭事件，改为隐藏到系统托盘"""
        event.ignore()
        self.hide()
        self.save_window_position()
        self.show_tray_message("Steam用户信息", "窗口已隐藏到系统托盘")


if __name__ == "__main__":
    app = QApplication(sys.argv)
    app.setQuitOnLastWindowClosed(False)

    # 设置中文字体
    font = QFont("Microsoft YaHei", 9)
    app.setFont(font)

    window = TransparentWindow()
    window.show()

    sys.exit(app.exec_())